<?php

/**
 * Maikuro Framework
 *
 * LICENSE:
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * The license is bundled with this package in the file LICENSE.txt.
 * You may also obtain a copy of the License at this URL:
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @copyright  Copyright (c) 2010, Jonathan Hedrén
 * @author     Jonathan Hedrén <jonathan.hedren@gmail.com>
 * @license    http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 */

/**
 * @see IDbHandler
 */
require_once 'IDbHandler.php';

/**
 * Database helper class.
 */
class DbHelper
{
    /**
     * The database handler (must implement the IDbHandler interface).
     *
     * @var IDbHandler
     */
    protected static $dbHandler;


    /**
     * Alters the table $table.
     *
     * @param string $table
     * @param string $changes
     * @return DbResult
     */
    public function alterTable($table, $changes)
    {
        $sql = 'ALTER TABLE ' . $table . ' ' . $changes;
        return $this->query($sql);
    }

    /**
     * Creates a database table.
     *
     * @param string $table
     * @param array $columns
     * @param boolean $ifNotExists
     * @param string $extras
     * @return DbResult
     */
    public function createTable($table, array $columns, $ifNotExists = true, $extras = null)
    {
        return $this->query($this->generateCreateTableSql($table, $columns, $ifNotExists, $extras));
    }

    /**
     * Drops the table $table.
     *
     * @param string $table
     * @return DbResult
     */
    public function dropTable($table)
    {
        return $this->query('DROP TABLE ' . $table);
    }

    /**
     * Generates the SQL to use for table creation.
     *
     * @param string $table
     * @param array $columns
     * @param boolean $ifNotExists
     * @param string $extras
     * @return string
     */
    protected function generateCreateTableSql($table, array $columns, $ifNotExists, $extras)
    {
        $sql = 'CREATE TABLE ';
        if ($ifNotExists) {
            $sql .= 'IF NOT EXISTS ';
        }
        $sql .= $table . ' (';
        $columnsCount = count($columns);
        $i = 0;
        foreach ($columns as $columnName => $columnDefinition) {
            $sql .= $columnName . ' ';
            if (!isset($columnDefinition['Type'])) {
                throw new Exception('Unknown column type for column "' . $columnName . '".');
            }
            $sql .= $columnDefinition['Type'];
            if (isset($columnDefinition['Length'])) {
                $sql .= '(' . $columnDefinition['Length'] . ')';
            }
            $sql .= ' ';
            if (isset($columnDefinition['Unsigned'])) {
                $sql .= 'UNSIGNED ';
            }
            if (isset($columnDefinition['NotNull']) && $columnDefinition['NotNull']) {
                $sql .= 'NOT NULL ';
            }
            if (isset($columnDefinition['CharacterSet'])) {
                $sql .= 'CHARACTER SET ' . $columnDefinition['CharacterSet'] . ' ';
            }
            if (isset($columnDefinition['Default'])) {
                $sql .= 'DEFAULT ' . $columnDefinition['Default'] . ' ';
            }
            if (isset($columnDefinition['PrimaryKey'])) {
                $sql .= 'PRIMARY KEY ';
            }
            if (isset($columnDefinition['Unique'])) {
                $sql .= 'UNIQUE ';
            }
            if (isset($columnDefinition['ForeignKey'])) {
                $sql .= 'FOREIGN KEY REFERENCES ' . $columnDefinition['ForeignKey'] . ' ';
            }
            if (isset($columnDefinition['Check'])) {
                $sql .= 'CHECK (' . $columnDefinition['check'] . ') ';
            }
            // TODO: Allow for other DBs than MySQL (IDENTITY, AUTOINCREMENT, SERIAL etc)
            if (isset($columnDefinition['AutoIncrement'])) {
                $sql .= 'AUTO_INCREMENT';
            }
            if ($columnsCount !== ++$i) {
                $sql .= ',';
            }
        }
        $sql .= ') ' . $extras;
        return $sql;
    }

}